<?php
/*
Plugin ID: cn.usephp.cache.memcached
Plugin Name: Memcache 缓存
Plugin URI: http://www.usephp.cn/plugins/memcache.html
Description: 使用memcache为整系统提供缓存功能。此插件依赖php Memcache 扩展。
Author: Leo Ning
Version: 1.0
Author URI: http://www.usephp.cn/
Option: mcache
*/
//添加配置选项
bind ( 'get_core_option_group', 'get_core_option_group_for_mcache' );
function get_core_option_group_for_mcache($groups) {
	$groups ['mcache'] = '<i class="icon-time"></i>缓存设置';
	return $groups;
}
bind ( 'get_option_mcache', 'get_option_mcache_option' );
//读取缓存配置 
function get_option_mcache_option($options) {
	if (file_exists ( APPDATA_PATH . 'mcache.dat' )) {
		$options ['mcache_host'] = file_get_contents ( APPDATA_PATH . 'mcache.dat' );
	}
	return $options;
}
//配置表单
bind ( 'show_option_control', 'show_mcache_option_control', 2, 3 );
function show_mcache_option_control($ctlrs, $group, $options) {
	if ($group != 'mcache') {
		return $ctlrs;
	}
	$opts = array ();
	$enabled = extension_loaded ( 'memcache' ) ? '<span class="label label-success">可用</span>' : '<span class="label">未安装</span>';
	$opts [] = '<div class="control-group ">
	          		<label for="mcache_host" class="control-label">Memcache扩展</label>
	            	<div class="controls">' . $enabled . '</div>
	          	</div>';
	$opts [] = '<div class="control-group ">
	          		<label for="mcache_host" class="control-label">缓存服务器</label>
	            	<div class="controls">
	              		<textarea rows="10" class="span5" name="opt[mcache][mcache_host]" id="mcache_host">' . $options ['mcache_host'] . '</textarea><br/>
	              		<span class="help-inline">一个服务器一行,格式如下：<br/><strong>localhost:11211@23</strong><br/>其中localhost为主机，11211为端口，23为权重.</span>
	            	</div>
	          	</div>';
	$ctlrs .= implode ( "\n", $opts );
	return $ctlrs;
}
//保存配置
bind ( 'on_save_option_mcache', 'on_save_option_mcache' );
function on_save_option_mcache($options) {
	$mcache_host = $options ['mcache'] ['mcache_host'];
	$rst = @file_put_contents ( APPDATA_PATH . 'mcache.dat', $mcache_host );
	if ($rst) {
		return true;
	} else {
		return '无法保存缓存配置文件.';
	}
}

class MCachedImpl implements ICache {
	private $enabled = false;
	private $servers = array ();
	private $mcacher;
	public function __construct() {
		if (extension_loaded ( 'memcache' )) {
			if (file_exists ( APPDATA_PATH . 'mcache.dat' )) {
				$mcache_hosts = file ( APPDATA_PATH . 'mcache.dat' );
				if (! empty ( $mcache_hosts )) {
					$this->mcacher = new Memcache ();
					foreach ( $mcache_hosts as $host ) {
						if (preg_match ( '/([^:]+):(\d+)@(\d+)/', $host, $m )) {
							$this->servers [] = array ($m [1], $m [2], $m [3] );
							$this->mcacher->addServer ( $m [1], $m [2] );
						}
					}
					if (! empty ( $this->servers )) {
						$this->enabled = true;
					}
				}
			}
		}
	}
	/* (non-PHPdoc)
	 * @see ICache::add()
	 */
	public function add($key, $value, $expire = 0, $group = 'default') {
		if ($this->enabled) {
			return $this->mcacher->set ( $key, $value, MEMCACHE_COMPRESSED, $expire );
		}
		return false;
	}
	
	/* (non-PHPdoc)
	 * @see ICache::clear()
	 */
	public function clear($check = true, $group = 'default') {
		if ($this->enabled) {
			return $this->mcacher->flush ();
		}
		return false;
	}
	
	/* (non-PHPdoc)
	 * @see ICache::delete()
	 */
	public function delete($key, $group = 'default') {
		if ($this->enabled) {
			return $this->mcacher->delete ( $key );
		}
		return false;
	}
	
	/* (non-PHPdoc)
	 * @see ICache::get()
	 */
	public function get($key, $group = 'default') {
		if ($this->enabled) {
			return $this->mcacher->get ( $key );
		}
		return null;
	}
	public function __destruct() {
		if ($this->mcacher) {
			$this->mcacher->close ();
		}
	}
}
//提供缓存驱动
bind ( 'get_cache_driver', 'create_mcacheimpl_instance' );
function create_mcacheimpl_instance($driver) {
	if (empty ( $driver )) {
		$driver = new MCachedImpl ();
	}
	return $driver;
}